const axios = require('axios');

// 微信ACCESS_TOKEN缓存对象
let accessTokenCache = {
  token: null,
  expireTime: 0
};

/**
 * 通过openid向微信服务器查询用户信息
 * @param {string} openid - 用户的openid
 * @param {string} accessToken - 微信API访问令牌
 * @returns {Promise<Object>} 用户信息
 */
async function getUserInfoByOpenid(openid, accessToken) {
  try {
    const response = await axios.get(`https://api.weixin.qq.com/cgi-bin/user/info?access_token=${accessToken}&openid=${openid}&lang=zh_CN`);

    if (response.data.errcode) {
      throw new Error(`WeChat API error: ${response.data.errmsg}`);
    }

    return response.data;
  } catch (error) {
    throw new Error(`Failed to get user info from WeChat: ${error.message}`);
  }
}

/**
 * 从微信服务器获取最新的ACCESS_TOKEN
 * @returns {Promise<string>} 访问令牌
 */
async function fetchAccessTokenFromWechat() {
  try {
    const response = await axios.get('https://api.weixin.qq.com/cgi-bin/token', {
      params: {
        grant_type: 'client_credential',
        appid: process.env.WECHAT_APPID,
        secret: process.env.WECHAT_APPSECRET
      }
    });
    if (response.data.errcode) {
      throw new Error(`Failed to fetch access token: ${response.data.errmsg}`);
    }

    // 缓存token并设置过期时间（提前5分钟过期）
    accessTokenCache.token = response.data.access_token;
    accessTokenCache.expireTime = Date.now() + (response.data.expires_in - 300) * 1000;

    return response.data.access_token;
  } catch (error) {
    throw new Error(`WeChat API error: ${error.message}`);
  }
}

/**
 * 获取微信API访问令牌（带缓存机制）
 * @returns {Promise<string>} 访问令牌
 */
async function getAccessToken() {
  // 检查缓存是否有效
  if (accessTokenCache.token && Date.now() < accessTokenCache.expireTime) {
    return accessTokenCache.token;
  }

  // 缓存过期或不存在，重新获取
  return await fetchAccessTokenFromWechat();
}

/**
 * 通过js_code获取微信用户的openid和session_key
 * @param {string} jsCode - 小程序登录时获取的code
 * @returns {Promise<Object>} 包含openid和session_key的对象
 */
async function jscode2session(jsCode) {
  try {
    const response = await axios.get(`https://api.weixin.qq.com/sns/jscode2session`, {
      params: {
        appid: process.env.WECHAT_APPID,
        secret: process.env.WECHAT_APPSECRET,
        js_code: jsCode,
        grant_type: 'authorization_code'
      }
    });

    if (response.data.errcode) {
      throw new Error(`WeChat jscode2session error: ${response.data.errmsg}`);
    }

    return response.data;
  } catch (error) {
    throw new Error(`Failed to get session info from WeChat: ${error.message}`);
  }
}

module.exports = {
  getUserInfoByOpenid,
  getAccessToken,
  jscode2session
};
